﻿using System;
using System.Collections.Generic;
using System.Configuration;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading.Tasks;

namespace VideoConverter
{
    class Program
    {
        private static string[] VideoFormat { get; set; } = ConfigurationManager.AppSettings["video_format"].Split(',');
        private static string CurrentDir { get; set; } = Directory.GetCurrentDirectory();
        static void Main(string[] args)
        {
            Console.WriteLine("INPUT BASEDIR:");
            var baseDir = Console.ReadLine();
            if (!Directory.Exists(baseDir))
            {
                Console.WriteLine("INPUT BASEDIR NO EXISTS");
                return;
            }
            foreach (var inputfile in Directory.GetFiles(baseDir, "*.*", SearchOption.AllDirectories))
            {
                if (!VideoFormat.Any(m => inputfile.ToLower().EndsWith(m.ToLower())))
                {
                    continue;
                }
                try
                {
                    VideoConvert(inputfile);
                }
                catch (Exception e)
                {
                    Console.WriteLine(e);
                }
            }
        }

        static void VideoConvert(string inputfile, string outformat = ".mp4")
        {
            var fileInfo = new FileInfo(inputfile);
            var outfile = inputfile.Replace(fileInfo.Extension, outformat);
            if (File.Exists(outfile))
            {
                return;
            }

            var videoInfo = GetVideoInfo(inputfile);
            var rate = videoInfo["pixel"] / 300;
            rate = rate > videoInfo["rate"] && videoInfo["rate"] != 0 ? videoInfo["rate"] : rate;
            var arguments = $"-y -i {inputfile} -b:v {rate}k -vcodec h264_nvenc -b:a 96K -acodec aac {outfile}";
            var p = new Process();
            p.StartInfo.FileName = $"{CurrentDir}\\ffmpeg.exe";
            p.StartInfo.Arguments = arguments;
            p.StartInfo.UseShellExecute = false;
            p.Start();
            p.WaitForExit();
        }

        static Dictionary<string, dynamic> GetVideoInfo(string inputfile)
        {
            var p = new Process();
            p.StartInfo.FileName = $"{CurrentDir}\\ffmpeg.exe";
            p.StartInfo.Arguments = $"-i {inputfile}";
            p.StartInfo.UseShellExecute = false;
            p.StartInfo.RedirectStandardOutput = true;
            p.StartInfo.RedirectStandardInput = true;
            p.StartInfo.RedirectStandardError = true;
            p.Start();
            p.WaitForExit();
            var videoInfo = new Dictionary<string, dynamic>();
            foreach (var line in p.StandardError.ReadToEnd().Split('\n'))
            {
                if (Regex.IsMatch(line, "Stream .*? Video:"))
                {
                    var match = Regex.Match(line, "(?<x>\\d{3,4})x(?<y>\\d{3,4})");
                    if (match.Success)
                    {
                        var x = Convert.ToInt32(match.Groups["x"].Value);
                        var y = Convert.ToInt32(match.Groups["y"].Value);
                        videoInfo["pixel"] = x * y;
                    }
                    else
                    {

                    }

                    match = Regex.Match(line, ", (?<x>\\d{3,6}) kb/s");
                    if (match.Success)
                    {
                        var x = Convert.ToInt32(match.Groups["x"].Value);
                        videoInfo["rate"] = x;
                    }
                    else
                    {
                        videoInfo["rate"] = 0;
                    }

                }
            }
            return videoInfo;
        }
    }
}
